import backtrader as bt
import backtrader.indicators as btind


class BollingerBandsStrategy(bt.Strategy):
    params = (
        ("period", 20),
        ("devfactor", 2),
    )

    def __init__(self):
        self.sma = btind.SimpleMovingAverage(self.data, period=self.params.period)
        self.stdev = btind.StandardDeviation(self.data, period=self.params.period)
        self.upper = self.sma + self.stdev * self.params.devfactor
        self.lower = self.sma - self.stdev * self.params.devfactor

    def next(self):
        if not self.position:
            if self.data.close[0] < self.lower[0]:
                self.buy()
        else:
            if self.data.close[0] > self.upper[0]:
                self.sell()


if __name__ == "__main__":
    cerebro = bt.Cerebro()
    data = bt.feeds.YahooFinanceData(
        dataname="AAPL", fromdate="2020-01-01", todate="2023-01-01"
    )
    cerebro.adddata(data)
    cerebro.addstrategy(BollingerBandsStrategy)
    cerebro.broker.setcash(10000.0)
    cerebro.addsizer(bt.sizers.PercentSizer, percents=90)
    print("Starting Portfolio Value: %.2f" % cerebro.broker.getvalue())
    cerebro.run()
    print("Final Portfolio Value: %.2f" % cerebro.broker.getvalue())
